﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpPcap;
using SharpPcap.AirPcap;
using SharpPcap.WinPcap;
using SharpPcap.LibPcap;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using PacketDotNet;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using Logic.Packet;
using Logic.Packet.Factories;
using Logic;
using GameProxy;
using System.IO;


namespace ConsolePacket
{
    public class T4CPack<T>
    {
        //private T GetData()
        //{
        //}
    }
    class Program
    {
        static void Main(string[] args)
        {
            //Paks.Init();
            //Proxy server = new Proxy();
            //PakClientFactory clientFactory = new PakClientFactory();
            byte[] world0 = File.ReadAllBytes(@"C:\Users\ix0u\Downloads\T4C Pak Process - Plugin AutoXp 2.0 (de Foxy)\T4CUWrld0.dat");
            string hexapak = new SoapHexBinary(world0).ToString();
            //server.RunWorkerAsync();

            ////proxy.Receive(new
            //// Print SharpPcap version
            //string ver = SharpPcap.Version.VersionString;
            //Console.WriteLine("SharpPcap {0}, Example3.BasicCap.cs", ver);

            //// Retrieve the device list
            //var devices = CaptureDeviceList.Instance;

            //// If no devices were found print an error
            //if (devices.Count < 1)
            //{
            //    Console.WriteLine("No devices were found on this machine");
            //    return;
            //}

            //Console.WriteLine();
            //Console.WriteLine("The following devices are available on this machine:");
            //Console.WriteLine("----------------------------------------------------");
            //Console.WriteLine();

            //int i = 0;

            //// Print out the devices
            //foreach (var dev in devices)
            //{
            //    /* Description */
            //    Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
            //    i++;
            //}

            //Console.WriteLine();
            //Console.Write("-- Please choose a device to capture: ");
            //i = int.Parse(Console.ReadLine());

            //var device = devices[i];

            //// Register our handler function to the 'packet arrival' event
            //device.OnPacketArrival +=
            //    new PacketArrivalEventHandler(device_OnPacketArrival);

            //// Open the device for capturing
            //int readTimeoutMilliseconds = 1000;
            //if (device is AirPcapDevice)
            //{
            //    // NOTE: AirPcap devices cannot disable local capture
            //    var airPcap = device as AirPcapDevice;
            //    airPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp, readTimeoutMilliseconds);
            //}
            //else if (device is WinPcapDevice)
            //{
            //    var winPcap = device as WinPcapDevice;
            //    winPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, readTimeoutMilliseconds);
            //}
            //else if (device is LibPcapLiveDevice)
            //{
            //    var livePcapDevice = device as LibPcapLiveDevice;
            //    livePcapDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
            //}
            //else
            //{
            //    throw new System.InvalidOperationException("unknown device type of " + device.GetType().ToString());
            //}

            //Console.WriteLine();
            //Console.WriteLine("-- Listening on {0} {1}, hit 'Enter' to stop...",
            //    device.Name, device.Description);

            //// Start the capturing process
            //string filter = "host 178.33.49.249 and udp";
            //device.Filter = filter;
            //device.StartCapture();

            //// Wait for 'Enter' from the user.
            Console.ReadLine();

            //// Stop the capturing process
            //device.StopCapture();

            //Console.WriteLine("-- Capture stopped.");

            //// Print out the device statistics
            //Console.WriteLine(device.Statistics.ToString());

            //// Close the pcap device
            //device.Close();
        }

        /// <summary>
        /// Prints the time and length of each received packet
        /// </summary>
        private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            var time = e.Packet.Timeval.Date;
            var len = e.Packet.Data.Length;
            var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
            UdpPacket udpPacket = PacketDotNet.UdpPacket.GetEncapsulated(packet);
            //TODO : WARNING DO NOT XOR IF Packet is ACK !

            string hexapak = new SoapHexBinary(udpPacket.PayloadData).ToString();

            byte[] data = DecryptionRoutine.DecryptPacket(udpPacket.PayloadData);

            //byte[] decodedPayloadData = DecryptionRoutine.Xor(udpPacket.PayloadData);
            PakClientFactory clientFactory = new PakClientFactory();
            PakServerFactory serverFactory = new PakServerFactory();
            if (udpPacket.DestinationPort == 11677)//PAKCLIENT
            {

                T4CBasePak pak = clientFactory.Parse(data);
                Console.BackgroundColor = ConsoleColor.Gray;
                Console.ForegroundColor = ConsoleColor.Blue;
                //Console.WriteLine("{0}:{1}:{2} Signature={3} pakID={4} actionId={5} seed={6}  ",
                //    time.Hour, time.Minute, time.Second, pak.Signature, pak.Id, pak.ActionID, pak.Seed);
                Console.WriteLine(string.Format("Client {0}", pak.Display()));


            }
            else//PAKSERVER
            {
                //if (data.Length > 2)
                //    data = DecryptionRoutine.Xor(udpPacket.PayloadData);

                T4CBasePak pak = serverFactory.Parse(data);
                Console.BackgroundColor = ConsoleColor.Gray;
                Console.ForegroundColor = ConsoleColor.DarkRed;
                //Console.WriteLine("{0}:{1}:{2} Signature={3} pakID={4} actionId={5}  ",
                //    time.Hour, time.Minute, time.Second, pak.Signature, pak.Id, pak.ActionID);
                Console.WriteLine(string.Format("Server {0}", pak.Display()));
            }
        }
    }
}
